<?php
/**
 * Specification of basic methods of module, all modules should extend this
 * class.
 *
 * @author Martin "DevelX" Jurča
 * @version 2010-01-20
 */
interface Module {
    /**
     * Name of the module. Must be the same as the name of the class.
     */
    protected $name = 'Module';

    /**
     * This is set to true when module can display some administration
     * interface.
     */
    protected $administrable = false;

    /**
     * Version string in format yyyy-mm-dd[ some optional string ].
     */
    protected $version = '2009-10-25';

    /**
     * Set to true only for system modules. System modules are installed within
     * system installation process.
     */
    protected $system  = false;

    /**
     * Versionstring of the lowest module's version compatible with the current
     * module version. Required for updates.
     */
    protected $compatible = '0000-01-01';

    /**
     * Details about module stored as multidimensional array.
     * Dependencies index is array of modules which this module requires for
     * its functionallity.
     * Observes is array of modules from which this module recieves events
     * fired by other modules. Special value 'ALL' can be used to recieve all
     * events from all modules (available for system modules only).
     * Localization is array of language codes representing languages to which
     * the module is fully localized - this is only for infomation purposes.
     */
    protected $details = array('dependencies' => array(),
            'observes' => array(),
            'localization' => array());

    /**
     * Localized first url part for displaying module. In this case the module
     * will be displayed by url: http://www.myhomepage.com/module/ and the
     * module administration would be displayed by url:
     * http://www.myhomepage.com/admin/module/
     * The form of the rest of the url always depends on curent module, but
     * all module-urls should begin with localized module url name.
     * If you leave this array empty, localized urls will be loaded
     * automatically from files lang/url-<lang code>.php in module's directory.
     *
     */
    protected $url = array('sk' => 'modul', 'cz' => 'modul', 'en' => 'module');

    /**
     * Rights for this module. These rights will be inported to user manager on
     * module's install and are used to give different users diferent rights
     * for managing the module.
     * Right are stored in this way:
     *     right := string | array
     *    string := right id name, right required for assignment will be set to
     *              Users::DEFAULT_REQUIRE
     *     array := 'id' => right id name, 'req' => right required for
     *          assignment
     */
    protected $rights = array(
            array('id' => 'Module_can_read', array('id' => 'Module_can_write',
                    'req' => '_assign admin rights')));

    /**
     * Array containing localized labels.
     *
     * @var Array localized labels.
     */
    protected $langArray;

    /**
     * The database driver object.
     *
     * @var DBDriver Database driver.
     */
    protected $dbdriver;

    /**
     * The database API object.
     *
     * @var DBAPI Database API.
     */
    protected $dbapi;

    /**
     * RecordList API object.
     *
     * @var RecordList
     */
    protected $recordList;

    /**
     * Confirmation messages.
     *
     */
    const MSG_CONFIRM = 0;

    /**
     * Notice messages.
     *
     */
    const MSG_NOTICE = 1;

    /**
     * Warning messages.
     *
     */
    const MSG_WARNING = 2;

    /**
     * Error messages.
     *
     */
    const MSG_ERROR = 3;

    /**
     * The constructor of module. Sets the links to the database driver and API
     * and loads the language.
     *
     * @param DBAPI $dbapi The Database API object.
     * @param RecordList $recordList The RecordList API object.
     */
    public function __construct(DBAPI $dbapi, RecordList $recordList);

    /**
     * Returns system name of the module.
     *
     * @return String System name of the module.
     */
    public function getName();

    /**
     * Returns localized user-friendly name of the module.
     *
     * @return Localized user-friendly name of the module.
     */
    public function getUIName();

    /**
     * Returns localized description of the module.
     *
     * @return Localized description of the module.
     */
    public function getDescription();

    /**
     * Returns module's details as specified in protected field $details.
     *
     * @return Array Module's details.
     */
    public function getDetails();

    /**
     * Returns localized module url prefixes as specified in protected field
     * $url.
     *
     * @return Array Localized module prefixes.
     */
    public function getUrls();

    /**
     * Returns rights specifications for this module as specified in protected
     * field $rights.
     *
     * @return Array Rights specification of the module.
     */
    public function getRights();

    /**
     * Return true if the module is part of the system.
     *
     * @return boolean True if the module is system module, false otherwise.
     */
    public function isSystem();

    /**
     * Returns true if the module has administration interface.
     *
     * @return boolean True if the module has administration interface.
     */
    public function isAdministrable();

    /**
     * Returns current version of the module.
     *
     * @return String Version string.
     */
    public function getVersion();

    /**
     * Returns the least version of module compatible with current.
     *
     * @return String Version string.
     */
    public function getCompatible();

    /**
     * Retrievs information that should be put in meta fields of head element
     * (title, description, ...)
     *
     * @param String $field Field name in lowercase
     * @param String $url URL of page for which field content is required
     */
    public function getMetaInfo($field, $url);

    /**
     * Installs the module so it can be fully used. May return true on success
     * or error string on fail.
     *
     * @return True on success, error string on fail.
     */
    public function install();

    /**
     * Uninstalls the module from the system. May return true on success or
     * error string on fail.
     *
     * @return True on success, error string on fail.
     */
    public function uninstall();

    /**
     * This special function is invoked by View module on each module that will
     * be displayed before any output has been sent to client thus giving the
     * modules possibility to register additional css and js files and
     * messages.
     * Current implementation will try to guess from $param variable, dislay
     * mode and / or current URL corresponding method and invoke it with
     * required parameters: initDisplayPublicList($cat, $page = 1), etc...
     *
     * @param mixed $param Additional parameter for the display function
     *        affecting for displaying what the modul should initialize.
     */
    public function initDisplay($param = null);

    /**
     * Displays the module according to system mode and optional parameter and
     * global request arrays ($_GET, ...).
     * Current implementation will try to guess from $param variable, dislay
     * mode and / or current URL corresponding method and invoke it with
     * required parameters: initDisplayPublicList($cat, $page = 1), etc...
     *
     * @param mixed $param Additional parameter for display function affecting
     *        what will the module display.
     */
    public function display($param = null);

    /**
     * Returns lines to be written to the main .htaccess file that are required
     * by the module.
     *
     * @return Lines of settings to be written to main .htaccess file.
     */
    public function getHtaccess();

    /**
     * Fills provided record with the data provided by event details.
     *
     * @param Array $record Record definition-
     * @param Array $data Data array.
     * @return Array Filled-in record
     */
    protected function fillRecord($record, $data);

    /**
     * Fills an array of records by the data provided by event details.
     *
     * @param Array $record
     * @param Array $data Data array.
     */
    protected function fillRecordList($record, $data);

    /**
     * The default display method that is invoked anytime the display method
     * fails to find requested content-displaying method using reflection based
     * on information extracted from the $param parameter or URL.
     *
     * @param mixed $param Additional parameter for displayBlank function
     *        possibly affecting what will the module display.
     */
    protected function displayBlank($param = null);

    /**
     * Checks wheter current users has requested rights to manage content
     * managed by this module.
     *
     * @param String $rightId ID string of rights to check.
     * @return boolean True if the current user has requested rights, false
     *         otherwise.
     */
    protected function hasRights($rightId);

    /**
     * Event handler for event named 'event'. There should be separated event
     * handler for each of events that the module can handle. These are not
     * required, module does not have to listen to events at all or listen just
     * to some of them. Running the event handlers are manadged by system
     * modules and first the module is checked for presence of event handler,
     * so you don't have to create empty event handler for each possible event
     * that may occour.
     * The name of event handler is derived from the name of the event. For
     * example, when event named "fooBoo" is fired, the name for event handler
     * is created from name of event by capitalizing the name of event and
     * adding "on" as a prefix. So in this case, the system will try to execute
     * event handler named "onFooBoo".
     * Events can be fired in two ways: from a module during system run or
     * externally from http request. When firing event from module, you may
     * "sign" the event by module name as event's source, but it is not
     * required if you are sure that the name of fired event is
     * unique in the whole system and no other modules use it.
     * When firing an event externally, there are several fields that needs to
     * be filled out. You need to fill out the field named 'event' with name of
     * event. Other optional fields are 'details' that will be given to event
     * handler as the first argument. If ommited, the event handler will
     * recieve a null. You may specify the event source using 'source' field by
     * providing name of the module. There is also one special field that
     * affects only events fired externaly from http request - field named
     * 'target'. Using this field you may specify one target module that will
     * recieve the event and no other modules will recieve the event. If
     * ommited, the event is delivered to all modules, becouse all modules
     * recieve external events automatically. Event handlers normally does not
     * return any data unless for a special type of event - warnings. When
     * module fires a warning event, each event handler may return any data.
     * Data from all modules are then returned to source module in associative
     * array indexed by names of the modules.
     * System modules can define special event listener method
     * &onALL($event, &$detials, $source = ''). This method is something like
     * universal event handler and will recieve all events that are not handled
     * by specialized event handlers, e.g. onFoo(). Name of the event is given
     * in first method paramter $event, the rest of the parameters has the same
     * meaning as those of stadard event handler.
     *
     * @param mixed $details Event details, any data that specifing details of
     *        the event.
     * @param String $source Name of the module that has fired the event.
     * @return mixed Any data to be returned to event's source module. Used
     *         only with warning events.
     */
    /**
     * --> This is not module method, its just a template how an event handler
     * --> should look like.
     * public function &onEvent(&$details, $source = '');
     */

    /**
     * Returns path to module directory not ended with slash. Additional path
     * (to file, to directory, ...) can be specified and will be appended.
     *
     * @param String $path Path to append afted path do module directory.
     * @param boolean $relative When set to true, method will return path
     *        relative to system root directory. Otherwise the method returns
     *        absolute path.
     * @return Relative or absolute path to file or directory in module
     *         directory.
     */
    protected function getDir($path = '', $relative = false);

    /**
     * Returns absolute web-public path for displaying module as active. This
     * url should be SEO compatible.
     *
     * @param string $path Path to be appended to the generated path.
     * @param string $event Name of the event that should be fired using this
     *        this link. This event will be delivered only to this module.
     * @return Absolute web-public path with appended string for displaying
     *         module as active of for processing data by module.
     */
    protected function getLink($path = '', $event = '');

    /**
     * Creates form begging that will invoke event in system after sending.
     *
     * @param string $event Name of the event.
     * @param boolean $source When set to true, form will send also information
     *        about module that has created the form.
     * @param mixed $target May be string representing name of target module or
     *        false if the event should be delivered to all modules.
     * @param mixes $onsubmit When set to string it defines name of the
     *        JavaScript function of which return value will decide upon
     *        submitting this form. The function will recieve one argument -
     *        the form HTML element object.
     * @return string Returns HTML definition of form with metadata in hidden
     *         input elements.
     */
    protected function getForm($event, $source = false, $target = false,
            $onsubmit = false);

    /**
     * Returns localized label by key. Label may be a special template that may
     * be filled with additional parameters specified in the second parameter.
     * Template parameters are allways numbers and can be used in two ways: to
     * format a number or to make choise from multiple values. These template
     * sequences must be enclosed in curly brackets { }. Template sequence is
     * specifyied by this grammar:
     *     <template> := {<number>} | {<choise>}
     *       <number> := <parameter number>n<nfs>
     *          <nfs> := #<nfs> | <any character><nfs> | # | <any character>
     *       <choise> := <parameter number>c<sequence>
     *     <sequence> := <option> | <option>|<sequence>
     *       <option> := <condition>$<value>
     *    <condition> := <number> | <number>> | <number>< | !<number>
     * If you need to use characters #, {, } or | in templates, you can escape
     * them by backslash: \#. In <value> will be # character replaced for
     * parameter value with the same formatting as in number format sequence.
     * Example:
     *    template: I {0c0$don't} have {0c0$any|!0$## ###} pen{0c!1$s}.
     *    lang('tpl', array(0)): I don't have any pens.
     *    lang('tpl', array(1)): I have 1 pen.
     *    lang('tpl', array(10000): I have 10 000 pens.
     * Sometimes may occour that requested label is not set or no language is
     * loaded at all. In such case this method returns the key.
     *
     * @param String $key Localized label key.
     * @param Array $params Optional parameters for template labels.
     * @return String Formatted localized label.
     */
    protected function lang($key, &$params = array());

    /**
     * Displays SMARTY templates using variables given by second parameter. The
     * templates are usually located in the templates directory in the module
     * directory. Only exception are override templates that overrides the
     * stardard module templates and are always connected with specific theme.
     *
     * @param String $name Name of the template.
     * @param Array $params Parameters for SMARTY template.
     */
    protected function template($name, &$params = array());

    /**
     * Adds messages for user to be displayed. Should be used within event
     * handlers or initDisplay method.
     *
     * @param String $message Message key to be added. The message will be
     *        loaded from lang method.
     * @param int $level Message level - one of MSG_CONFIRM, MSG_NOTICE,
     *      MSG_WARNING, MSG_ERROR;
     */
    protected function addMsg($message, $level);

    /**
     * Chooses language code from available languages.
     *
     * @param Array $from Array containing available languages. They may be
     *        defined as values of nuberic array or keys of asociative array.
     * @return String language code
     */
    protected function chooseLocale(&$from);

    /**
     * Returns from array of localized label the one that suits the bets the
     * current language (uses chooseLocale method).
     *
     * @param Array $from Array of localized labels, keys should be language
     *        codes.
     * @return mixed Localized label or whatever value under selected key.
     */
    protected function getLocale(&$from);

    /**
     * Loads localization for submit button and item labels.
     *
     * @param Array $form A form definition.
     */
    protected function prepareFormData(&$form);

    /**
     * Loads localization for menu items and titles and prepares links.
     *
     * @param Array $menu menu definition
     */
    protected function prepareMenu(&$menu);
}
?>
